package com.hb.trade.api.routine.controller.project.opening;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.hb.core.pojo.project.opening.dto.OpeningBidTenderDTO;
import com.hb.core.pojo.project.opening.dto.OpeningBidTenderRecordDTO;
import com.hb.core.pojo.project.opening.entity.OpeningBidInfo;
import com.hb.core.pojo.project.opening.entity.OpeningBidTender;
import com.hb.core.pojo.project.proj.entity.AbstractProject;
import com.hb.core.pojo.project.proj.enums.BidWayEnum;
import com.hb.core.pojo.project.section.dto.BidSectionDTO;
import com.hb.core.pojo.project.section.dto.BidSectionTenderDTO;
import com.hb.trade.api.routine.controller.util.ScheduleExcelService;
import com.hb.trade.client.project.BidOpeningClient;
import com.hb.trade.client.project.BidOpeningHallClient;
import com.hb.trade.client.project.ProjectClient;
import com.hb.trade.client.project.SectionClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.fzzn.core.auth.shiro.util.ShiroUtil;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.msg.ResponseDto;
import org.fzzn.core.util.Enums;
import org.fzzn.core.util.ResultUtil;
import org.fzzn.core.web.anno.Version;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 开标大厅相关Api控制层
 *
 * @author Lix1ang
 * @date 2022-1-12 13:48:55
 */
@Version(1.0)
@RestController
@RequestMapping("/{version}")
@Api(tags = "开标大厅", value = "BidOpeningHall")
public class ApiBidOpeningHallController {


   protected final BidOpeningHallClient openingHallClient;
   protected final SectionClient sectionClient;
   protected final ProjectClient projectClient;
   protected final BidOpeningClient bidOpeningClient;

    public ApiBidOpeningHallController(BidOpeningHallClient openingHallClient,
                                       SectionClient sectionClient,
                                       ProjectClient projectClient, BidOpeningClient bidOpeningClient) {
        this.openingHallClient = openingHallClient;
        this.sectionClient = sectionClient;
        this.projectClient = projectClient;
        this.bidOpeningClient = bidOpeningClient;
    }


    @ApiOperation(value = "获取开标大厅是否满足条件", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sectionId", value = "标段Id", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/satisfyConditionFlag")
    public ResponseDto pageTodayBidOpeningSection(@RequestBody BidSectionTenderDTO bidSectionTender) {
        if (bidSectionTender.getSectionId() == null){
            return ResultUtil.fail(MsgEnum.INCORRECT_PARAM);
        }
        Message<AbstractProject> abstractProjectMessage = projectClient.detailBySectionId(bidSectionTender.getSectionId());
        if (abstractProjectMessage.isSuccess()
                && abstractProjectMessage.getData() != null
                && Enums.equals(BidWayEnum.SINGLE,abstractProjectMessage.getData().getBidWay())){
            return ResultUtil.msg(true);

        }
        bidSectionTender.setStatus(1);
        Message<List<BidSectionTenderDTO>> list = sectionClient.listBidSectionTender(bidSectionTender);
        if (list.isFail() || CollUtil.isEmpty(list.getData())){
            return ResultUtil.fail("投标家数不足三家,无法开标");
        }
        List<BidSectionTenderDTO> data = list.getData();
        if (data.size() < 3){
            return ResultUtil.fail("投标家数不足三家,无法开标");
        }
        return ResultUtil.msg(true);
    }

    @ApiOperation(value = "根据项目Id查询今日开标标段分页", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "项目Id", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/pageTodayBidOpeningSection")
    public ResponseDto pageTodayBidOpeningSection(@RequestBody BidSectionDTO bidSectionDTO) {
        Integer roleSign = ShiroUtil.getExtInfo().get("roleSign", Integer.class);
        ShiroUtil.fillOwner(bidSectionDTO);
        bidSectionDTO.setRoleSign(roleSign);
        return ResultUtil.msg(openingHallClient.pageTodayBidOpeningSection(bidSectionDTO));
    }
    @ApiOperation(value = "根据项目Id查询今日开标标段分页", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "项目Id", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/listTodayBidOpeningSection")
    public ResponseDto listTodayBidOpeningSection(@RequestBody BidSectionDTO bidSectionDTO) {
        Integer roleSign = ShiroUtil.getExtInfo().get("roleSign", Integer.class);
        ShiroUtil.fillOwner(bidSectionDTO);
        bidSectionDTO.setRoleSign(roleSign);
        Message<List<BidSectionDTO>> listMessage = openingHallClient.listTodayBidOpeningSection(bidSectionDTO);
        return ResultUtil.msg(listMessage);
    }

    @ApiOperation(value = "根据标段Id查询开标记录表数据", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sectionId", value = "标段Id", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/getOpeningBidInfoBySectionId")
    public ResponseDto getOpeningBidInfoBySectionId(@RequestBody OpeningBidInfo openingBidInfo) {
        return ResultUtil.msg(openingHallClient.getOpeningBidInfoBySectionId(openingBidInfo));
    }

    @ApiOperation(value = "统计大厅各阶段人数（总投标人数、有效投标人数、无效投标人数、已解密人数、已签名人数）", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键Id", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/countHallInfo")
    public ResponseDto countHallInfo(@RequestBody OpeningBidInfo openingBidInfo) {
        return ResultUtil.msg(openingHallClient.countHallInfo(openingBidInfo));
    }

    @ApiOperation(value = "获取开标大厅实时记录数据(招标方)", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "openingBidInfoId", value = "开标记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/listBidOpeningAllRecord")
    public ResponseDto listBidOpeningAllRecord(@RequestBody OpeningBidTender openingBidTender) {
        Message<List<OpeningBidTenderRecordDTO>> message = openingHallClient.listBidOpeningAllRecord(openingBidTender);
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "获取开标大厅实时记录数据(投标方)", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "openingBidInfoId", value = "开标记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/listBidOpeningRecord")
    public ResponseDto listBidOpeningRecord(@RequestBody OpeningBidTender openingBidTender) {
        openingBidTender.setBidderId(ShiroUtil.getUserId());
        Message<List<OpeningBidTenderRecordDTO>> message = openingHallClient.listBidOpeningRecord(openingBidTender);
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "获取开标大厅投标方状态数据(招标方)", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "openingBidInfoId", value = "开标记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/listBidOpeningTender")
    public ResponseDto listBidOpeningTender(@RequestBody OpeningBidTender openingBidTender) {
        Message<List<OpeningBidTenderDTO>> message = openingHallClient.listBidOpeningTender(openingBidTender);
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "开始签到", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class),
    })
    @PostMapping("/hall/startSignin")
    public ResponseDto startSignin(@RequestBody OpeningBidInfo openingBidInfo) {
        Message message = openingHallClient.startSignin(openingBidInfo);
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "开始开标", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class),
    })
    @PostMapping("/hall/startBidOpening")
    public ResponseDto startBidOpening(@RequestBody OpeningBidInfo openingBidInfo) {
        Message message = openingHallClient.startBidOpening(openingBidInfo);
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "开始解密", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/startDecrypt")
    public ResponseDto startDecrypt(@RequestBody OpeningBidInfo openingBidInfo) {
        return ResultUtil.msg(openingHallClient.startDecrypt(openingBidInfo));
    }

    @ApiOperation(value = "结束解密", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/endDecrypt")
    public ResponseDto endDecrypt(@RequestBody OpeningBidInfo openingBidInfo) {
        return ResultUtil.msg(openingHallClient.endDecrypt(openingBidInfo));
    }

    @ApiOperation(value = "开始唱标", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/startSing")
    public ResponseDto startSing(@RequestBody OpeningBidInfo openingBidInfo) {
        openingBidInfo.setCreateId(ShiroUtil.getUserId());
        return ResultUtil.msg(openingHallClient.startSing(openingBidInfo));
    }

    @ApiOperation(value = "开始确认", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/startConfirm")
    public ResponseDto startConfirm(@RequestBody OpeningBidInfo openingBidInfo) {
        return ResultUtil.msg(openingHallClient.startConfirm(openingBidInfo));
    }


    @ApiOperation(value = "结束确认", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/endConfirm")
    public ResponseDto endConfirm(@RequestBody OpeningBidInfo openingBidInfo) {
        Message message = openingHallClient.endConfirm(openingBidInfo);
        return ResultUtil.msg(message);
    }

    @ApiOperation(value = "开标结束", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/endBidOpening")
    public ResponseDto endBidOpening(@RequestBody OpeningBidInfo openingBidInfo) {
        Message<OpeningBidInfo> openingBidInfoMessage = openingHallClient.endBidOpening(openingBidInfo);
        //结束开标生成开标一览表excel
        openingBidInfo.setNoShow(2);
        Message<List<OpeningBidTender>> listMessage = openingHallClient.viewBidOpeningSchedule(openingBidInfo);
        // 异步执行保存操作, 不占用当前线程资源
        ThreadUtil.execAsync(() -> ScheduleExcelService.scheduleExcel(listMessage.getData(),openingBidInfo.getId()));
        return ResultUtil.msg(openingBidInfoMessage);
    }

    @ApiOperation(value = "设置项目流标", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "flowReason", value = "流标原因", dataTypeClass = String.class)
    })
    @PostMapping("/hall/setFlowBid")
    public ResponseDto setFlowBid(@RequestBody OpeningBidInfo openingBidInfo) {
        return ResultUtil.msg(openingHallClient.setFlowBid(openingBidInfo));
    }

    @ApiOperation(value = "查看开标记录", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/getOpeningBidInfo")
    public ResponseDto getOpeningBidInfo(@RequestBody OpeningBidInfo openingBidInfo) {
        return ResultUtil.msg(openingHallClient.getOpeningBidInfo(openingBidInfo));
    }

    @ApiOperation(value = "查看开标一览表", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/viewBidOpeningSchedule")
    public ResponseDto viewBidOpeningSchedule(@RequestBody OpeningBidInfo openingBidInfo) {
        openingBidInfo.setCreateId(ShiroUtil.getUserId());
        openingBidInfo.setNoShow(1);
        Message<List<OpeningBidTender>> message = openingHallClient.viewBidOpeningSchedule(openingBidInfo);
        return ResultUtil.msg(message);
    }


    //------------------------------------------  投标方端接口  ------------------------------------------


    @ApiOperation(value = "根据开标记录Id与投标人Id查询投标方信息", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "openingBidInfoId", value = "开标标段记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/getOpeningBidTender")
    public ResponseDto getOpeningBidTender(@RequestBody OpeningBidTender openingBidTender){
        ShiroUtil.fillOwner(openingBidTender);
        openingBidTender.setBidderId(ShiroUtil.getUserId());
        return ResultUtil.msg(openingHallClient.getOpeningBidTender(openingBidTender));
    }

    @ApiOperation(value = "投标人签到", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段投标方记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/bidderSignin")
    public ResponseDto bidderSignin(@RequestBody OpeningBidTender openingBidTender) {
        return ResultUtil.msg(openingHallClient.bidderSignin(openingBidTender));
    }

    @ApiOperation(value = "投标人解密", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段投标方记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/bidderDecrypt")
    public ResponseDto bidderDecrypt(@RequestBody OpeningBidTender openingBidTender) {
        return ResultUtil.msg(openingHallClient.bidderDecrypt(openingBidTender));
    }

    @ApiOperation(value = "投标人确认", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "开标标段投标方记录表主键", dataTypeClass = Long.class)
    })
    @PostMapping("/hall/bidderComfirm")
    public ResponseDto bidderComfirm(@RequestBody OpeningBidTender openingBidTender) {
        return ResultUtil.msg(openingHallClient.bidderComfirm(openingBidTender));
    }

    @ApiOperation(value = "开标大厅查询未解密或未确认的投标人", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "openingBidInfoId", value = "开标标段投标方记录表主键", required = true, dataTypeClass = Long.class),
            @ApiImplicitParam(name = "queryType", value = "查询类型 1 解密  2 确认", dataTypeClass = Long.class)
    })
    @PostMapping("/openingBidTender/listByNotDecryptOrConfirm")
    public ResponseDto listByNotDecryptOrConfirm(@RequestBody OpeningBidTenderDTO openingBidTenderDTO) {
        if (openingBidTenderDTO.getOpeningBidInfoId() == null) {
            return ResultUtil.fail("缺少必要参数");
        }
        Message<List<OpeningBidTender>> message = this.bidOpeningClient.listByNotDecryptOrConfirm(openingBidTenderDTO);
        return ResultUtil.msg(message);
    }
}
